// src/config/settings.rs

use config::{Config, File, FileFormat, Environment};
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;
use std::path::PathBuf;
use anyhow::{Result, anyhow};
use log::LevelFilter;

/// 应用配置主结构
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Settings {
    /// 服务器配置
    pub server: ServerConfig,
    /// 华为云IoT平台配置
    pub huawei_cloud: HuaweiCloudConfig,
    /// OPC UA配置
    pub opcua: OPCUAConfig,
    /// 数据库配置（可选）
    pub database: Option<DatabaseConfig>,
    /// 日志配置
    pub logging: LoggingConfig,
    /// 安全配置
    pub security: SecurityConfig,
    /// 性能配置
    pub performance: PerformanceConfig,
    /// 应用场景特定配置
    pub scenarios: ScenarioConfigs,
}

/// 服务器配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerConfig {
    /// 服务器绑定地址
    pub host: String,
    /// 服务器端口
    pub port: u16,
    /// 工作线程数
    pub workers: usize,
    /// API前缀路径
    pub api_prefix: String,
    /// 请求超时时间（秒）
    pub request_timeout_secs: u64,
    /// 最大请求体大小（MB）
    pub max_body_size_mb: u64,
}

impl ServerConfig {
    /// 获取完整的服务器地址
    pub fn server_addr(&self) -> SocketAddr {
        format!("{}:{}", self.host, self.port)
            .parse()
            .expect("Invalid server address configuration")
    }
    
    /// 获取API基础路径
    pub fn api_base_path(&self) -> String {
        format!("{}/api", self.api_prefix)
    }
    
    /// 获取最大请求体大小（字节）
    pub fn max_body_size_bytes(&self) -> u64 {
        self.max_body_size_mb * 1024 * 1024
    }
}

/// 华为云IoT平台配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HuaweiCloudConfig {
    /// 华为云API基础地址
    pub base_url: String,
    /// 访问令牌
    pub access_token: String,
    /// 项目ID
    pub project_id: String,
    /// 请求超时时间（秒）
    pub timeout_secs: u64,
    /// 重试次数
    pub max_retries: u32,
    /// 重试间隔（毫秒）
    pub retry_delay_ms: u64,
    /// 产品模型缓存时间（秒）
    pub cache_ttl_secs: u64,
}

impl HuaweiCloudConfig {
    /// 获取产品列表API地址
    pub fn products_url(&self) -> String {
        format!("{}/v5/iotps/products", self.base_url)
    }
    
    /// 获取设备列表API地址
    pub fn devices_url(&self) -> String {
        format!("{}/v5/iotps/devices", self.base_url)
    }
    
    /// 获取健康检查API地址
    pub fn health_url(&self) -> String {
        format!("{}/v5/iotps/health", self.base_url)
    }
}

/// OPC UA配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OPCUAConfig {
    /// 命名空间URI
    pub namespace_uri: String,
    /// 端点URL
    pub endpoint_url: String,
    /// 安全策略
    pub security_policy: String,
    /// 消息模式
    pub message_mode: String,
    /// 会话超时时间（毫秒）
    pub session_timeout_ms: u32,
    /// 最大消息大小
    pub max_message_size: u32,
    /// 最大块数量
    pub max_chunk_count: u32,
}

impl OPCUAConfig {
    /// 验证OPC UA配置
    pub fn validate(&self) -> Result<()> {
        if self.namespace_uri.is_empty() {
            return Err(anyhow!("OPC UA namespace URI cannot be empty"));
        }
        if self.endpoint_url.is_empty() {
            return Err(anyhow!("OPC UA endpoint URL cannot be empty"));
        }
        Ok(())
    }
}

/// 数据库配置（可选）
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabaseConfig {
    /// 数据库连接URL
    pub url: String,
    /// 最大连接数
    pub max_connections: u32,
    /// 连接超时时间（秒）
    pub connect_timeout_secs: u64,
    /// 是否启用连接池
    pub enable_pool: bool,
    /// 连接池大小
    pub pool_size: u32,
}

/// 日志配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoggingConfig {
    /// 日志级别
    pub level: String,
    /// 日志文件路径（可选）
    pub file_path: Option<String>,
    /// 是否启用控制台输出
    pub enable_console: bool,
    /// 是否启用文件输出
    pub enable_file: bool,
    /// 日志文件最大大小（MB）
    pub max_file_size_mb: u64,
    /// 保留的日志文件数量
    pub max_files: u32,
}

impl LoggingConfig {
    /// 获取日志级别过滤器
    pub fn level_filter(&self) -> LevelFilter {
        match self.level.to_lowercase().as_str() {
            "error" => LevelFilter::Error,
            "warn" => LevelFilter::Warn,
            "info" => LevelFilter::Info,
            "debug" => LevelFilter::Debug,
            "trace" => LevelFilter::Trace,
            _ => LevelFilter::Info,
        }
    }
    
    /// 获取完整的日志文件路径
    pub fn full_file_path(&self) -> Option<PathBuf> {
        self.file_path.as_ref().map(|path| PathBuf::from(path))
    }
}

/// 安全配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecurityConfig {
    /// 是否启用HTTPS
    pub enable_https: bool,
    /// SSL证书路径（可选）
    pub ssl_cert_path: Option<String>,
    /// SSL密钥路径（可选）
    pub ssl_key_path: Option<String>,
    /// CORS允许的源
    pub cors_allowed_origins: Vec<String>,
    /// API密钥（可选）
    pub api_key: Option<String>,
    /// 是否启用认证
    pub enable_auth: bool,
}

/// 性能配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceConfig {
    /// 工作线程数
    pub worker_threads: usize,
    /// 最大并发连接数
    pub max_connections: usize,
    /// 连接超时时间（秒）
    pub connection_timeout_secs: u64,
    /// 请求超时时间（秒）
    pub request_timeout_secs: u64,
    /// 是否启用压缩
    pub enable_compression: bool,
    /// 缓存大小（MB）
    pub cache_size_mb: u64,
}

/// 应用场景配置集合
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScenarioConfigs {
    /// 生产制造场景配置
    pub manufacturing: ManufacturingConfig,
    /// 机器人应用场景配置
    pub robotics: RoboticsConfig,
    /// 供应链管理场景配置
    pub supply_chain: SupplyChainConfig,
    /// 交通工程场景配置
    pub transportation: TransportationConfig,
    /// 科研教学场景配置
    pub research_education: ResearchEducationConfig,
    /// 公共事业场景配置
    pub public_utilities: PublicUtilitiesConfig,
    /// 园区运营场景配置
    pub campus_operations: CampusOperationsConfig,
}

/// 生产制造场景配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ManufacturingConfig {
    /// 是否启用生产制造场景
    pub enabled: bool,
    /// 支持的设备类型
    pub supported_device_types: Vec<String>,
    /// 数据采集间隔（秒）
    pub data_collection_interval_secs: u64,
    /// 质量检测标准
    pub quality_standards: Vec<String>,
    /// 物料追溯配置
    pub material_traceability: MaterialTraceabilityConfig,
}

/// 机器人应用场景配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RoboticsConfig {
    /// 是否启用机器人应用场景
    pub enabled: bool,
    /// 支持的机器人协议
    pub supported_protocols: Vec<String>,
    /// 运动控制精度
    pub motion_control_precision: f64,
    /// 任务调度配置
    pub task_scheduling: TaskSchedulingConfig,
}

/// 通用配置结构
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MaterialTraceabilityConfig {
    pub enabled: bool,
    pub batch_size: usize,
    pub retention_days: u32,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskSchedulingConfig {
    pub max_concurrent_tasks: usize,
    pub task_timeout_secs: u64,
}

// 其他场景配置结构...
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SupplyChainConfig {
    pub enabled: bool,
    pub inventory_management: bool,
    pub logistics_tracking: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TransportationConfig {
    pub enabled: bool,
    pub traffic_monitoring: bool,
    pub vehicle_tracking: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResearchEducationConfig {
    pub enabled: bool,
    pub experimental_data: bool,
    pub academic_integration: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PublicUtilitiesConfig {
    pub enabled: bool,
    pub utility_monitoring: bool,
    pub resource_management: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CampusOperationsConfig {
    pub enabled: bool,
    pub facility_management: bool,
    pub energy_management: bool,
}

impl Settings {
    /// 创建新的配置实例
    pub fn new() -> Result<Self> {
        let environment = std::env::var("RUN_MODE")
            .unwrap_or_else(|_| "development".into());
        
        let config_path = std::env::var("CONFIG_PATH")
            .unwrap_or_else(|_| "config".into());
            
        let config = Config::builder()
            // 添加默认配置
            .add_source(File::with_name(&format!("{}/default", config_path)).required(false))
            // 添加环境特定配置
            .add_source(File::with_name(&format!("{}/{}", config_path, environment)).required(false))
            // 添加环境变量
            .add_source(Environment::with_prefix("OPCUA").separator("_"))
            .build()
            .map_err(|e| anyhow!("Failed to build configuration: {}", e))?;
            
        let settings: Settings = config.try_deserialize()
            .map_err(|e| anyhow!("Failed to deserialize configuration: {}", e))?;
            
        // 验证配置
        settings.validate()?;
        
        Ok(settings)
    }
    
    /// 验证配置完整性
    pub fn validate(&self) -> Result<()> {
        // 验证服务器配置
        if self.server.host.is_empty() {
            return Err(anyhow!("Server host cannot be empty"));
        }
        if self.server.port == 0 {
            return Err(anyhow!("Server port cannot be zero"));
        }
        
        // 验证华为云配置
        if self.huawei_cloud.base_url.is_empty() {
            return Err(anyhow!("Huawei Cloud base URL cannot be empty"));
        }
        if self.huawei_cloud.access_token.is_empty() {
            return Err(anyhow!("Huawei Cloud access token cannot be empty"));
        }
        
        // 验证OPC UA配置
        self.opcua.validate()?;
        
        // 验证日志配置
        if self.logging.level.is_empty() {
            return Err(anyhow!("Log level cannot be empty"));
        }
        
        Ok(())
    }
    
    /// 获取当前环境
    pub fn environment(&self) -> String {
        std::env::var("RUN_MODE").unwrap_or_else(|_| "development".into())
    }
    
    /// 检查是否为开发环境
    pub fn is_development(&self) -> bool {
        self.environment() == "development"
    }
    
    /// 检查是否为生产环境
    pub fn is_production(&self) -> bool {
        self.environment() == "production"
    }
    
    /// 获取启用的应用场景
    pub fn enabled_scenarios(&self) -> Vec<&str> {
        let mut scenarios = Vec::new();
        
        if self.scenarios.manufacturing.enabled {
            scenarios.push("manufacturing");
        }
        if self.scenarios.robotics.enabled {
            scenarios.push("robotics");
        }
        if self.scenarios.supply_chain.enabled {
            scenarios.push("supply_chain");
        }
        if self.scenarios.transportation.enabled {
            scenarios.push("transportation");
        }
        if self.scenarios.research_education.enabled {
            scenarios.push("research_education");
        }
        if self.scenarios.public_utilities.enabled {
            scenarios.push("public_utilities");
        }
        if self.scenarios.campus_operations.enabled {
            scenarios.push("campus_operations");
        }
        
        scenarios
    }
}

/// 默认配置实现
impl Default for Settings {
    fn default() -> Self {
        Self {
            server: ServerConfig {
                host: "127.0.0.1".to_string(),
                port: 8080,
                workers: 4,
                api_prefix: "/api".to_string(),
                request_timeout_secs: 30,
                max_body_size_mb: 10,
            },
            huawei_cloud: HuaweiCloudConfig {
                base_url: "https://iot-api.cn-north-4.myhuaweicloud.com".to_string(),
                access_token: "".to_string(), // 需要从环境变量设置
                project_id: "".to_string(), // 需要从环境变量设置
                timeout_secs: 30,
                max_retries: 3,
                retry_delay_ms: 1000,
                cache_ttl_secs: 300,
            },
            opcua: OPCUAConfig {
                namespace_uri: "urn:huawei:opcua:converter".to_string(),
                endpoint_url: "opc.tcp://localhost:4840".to_string(),
                security_policy: "Basic256Sha256".to_string(),
                message_mode: "SignAndEncrypt".to_string(),
                session_timeout_ms: 30000,
                max_message_size: 65536,
                max_chunk_count: 1024,
            },
            database: None,
            logging: LoggingConfig {
                level: "info".to_string(),
                file_path: Some("logs/application.log".to_string()),
                enable_console: true,
                enable_file: true,
                max_file_size_mb: 100,
                max_files: 10,
            },
            security: SecurityConfig {
                enable_https: false,
                ssl_cert_path: None,
                ssl_key_path: None,
                cors_allowed_origins: vec],
                api_key: None,
                enable_auth: false,
            },
            performance: PerformanceConfig {
                worker_threads: 4,
                max_connections: 1000,
                connection_timeout_secs: 30,
                request_timeout_secs: 30,
                enable_compression: true,
                cache_size_mb: 100,
            },
            scenarios: ScenarioConfigs {
                manufacturing: ManufacturingConfig {
                    enabled: true,
                    supported_device_types: vec, "CNC".to_string(), "Robot".to_string()],
                    data_collection_interval_secs: 5,
                    quality_standards: vec, "IATF16949".to_string()],
                    material_traceability: MaterialTraceabilityConfig {
                        enabled: true,
                        batch_size: 1000,
                        retention_days: 365,
                    },
                },
                robotics: RoboticsConfig {
                    enabled: true,
                    supported_protocols: vec, "Profinet".to_string()],
                    motion_control_precision: 0.01,
                    task_scheduling: TaskSchedulingConfig {
                        max_concurrent_tasks: 10,
                        task_timeout_secs: 300,
                    },
                },
                supply_chain: SupplyChainConfig {
                    enabled: true,
                    inventory_management: true,
                    logistics_tracking: true,
                },
                transportation: TransportationConfig {
                    enabled: true,
                    traffic_monitoring: true,
                    vehicle_tracking: true,
                },
                research_education: ResearchEducationConfig {
                    enabled: true,
                    experimental_data: true,
                    academic_integration: true,
                },
                public_utilities: PublicUtilitiesConfig {
                    enabled: true,
                    utility_monitoring: true,
                    resource_management: true,
                },
                campus_operations: CampusOperationsConfig {
                    enabled: true,
                    facility_management: true,
                    energy_management: true,
                },
            },
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_default_settings() {
        let settings = Settings::default();
        assert_eq!(settings.server.port, 8080);
        assert!(settings.scenarios.manufacturing.enabled);
    }

    #[test]
    fn test_server_config() {
        let server_config = ServerConfig {
            host: "127.0.0.1".to_string(),
            port: 8080,
            workers: 4,
            api_prefix: "/api".to_string(),
            request_timeout_secs: 30,
            max_body_size_mb: 10,
        };
        
        assert_eq!(server_config.server_addr().to_string(), "127.0.0.1:8080");
        assert_eq!(server_config.api_base_path(), "/api/api");
        assert_eq!(server_config.max_body_size_bytes(), 10485760);
    }

    #[test]
    fn test_huawei_cloud_urls() {
        let huawei_config = HuaweiCloudConfig {
            base_url: "https://iot-api.example.com".to_string(),
            access_token: "test".to_string(),
            project_id: "test".to_string(),
            timeout_secs: 30,
            max_retries: 3,
            retry_delay_ms: 1000,
            cache_ttl_secs: 300,
        };
        
        assert_eq!(huawei_config.products_url(), "https://iot-api.example.com/v5/iotps/products");
        assert_eq!(huawei_config.health_url(), "https://iot-api.example.com/v5/iotps/health");
    }
}